package com.zx.mes.senior.lambda;

import lombok.extern.java.Log;
import org.junit.Before;
import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * lambda 测试
 *
 * @author huayunlong
 * @date 2018-8-10
 */
@Log
public class LambdaTest {

    List<Person> personList = new ArrayList<>();

    Person[] persons = {
            new Person("11","11",11),
            new Person("22","22",22),
            new Person("33","33",33),
    };

    @Before
    public void set() {
        Person person = new Person();
        person.setId("1");
        person.setName("1");
        person.setAge(5);
        personList.add(person);

        Person person2 = new Person();
        person2.setId("2");
        person2.setName("2");
        person2.setAge(2);
        personList.add(person2);

        Person person3 = new Person();
        person3.setId("3");
        person3.setName("这是3");
        person3.setAge(12);
        personList.add(person3);

        Person person4 = new Person();
        person4.setId("4");
        person4.setName("这是4");
        person4.setAge(8);
        personList.add(person4);
        /// 数组静态初使化这种情况不允许
//        persons = {person,person2};
    }

    @Test
    public void test() {
        add(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

    }

    @Test
    public void test2() {
        for (int i = 0; i < personList.size(); i++) {
            System.out.println(personList.get(i).toString());
        }

        System.out.println("----------------------------------------");

        personList.forEach((person) -> System.out.println(person.toString()));

        System.out.println("----------------------------------------");

        /// person -> person.getAge()
        // / 可以替换成
        /// Person::getAge
        ///  表达式
        /// () -> new HashMap<>();
        /// 可以替换成
        /// HashMap::new
        personList.forEach(System.out::println);
    }

    @Test
    public void test3() {
        Runnable runnable = () -> System.out.println("匿名内部内例子!");
        Thread thread = new Thread(runnable);
        thread.start();

        System.out.println("----------------------------------------");

        Thread thread2 = new Thread(() -> System.out.println("匿名内部类的例子!"));
        thread2.start();

        System.out.println("----------------------------------------");

        new Thread(() -> System.out.println("匿名内部类的例子!")).start();

    }

    @Test
    public void test4() {

        Collections.sort(personList, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                return o1.getAge() - o2.getAge();
            }
        });
        System.out.println(personList);
    }

    @Test
    public void test5() {
        Collections.sort(personList, (Person o1, Person o2) -> o1.getAge() - o2.getAge());
        System.out.println(personList);
    }

    /**
     * 最简的写法
     */
    @Test
    public void test6() {
        Collections.sort(personList, Comparator.comparingInt(Person::getAge));
        System.out.println(personList);
    }

    @Test
    public void test7() {
        Collections.sort(personList, (o1, o2) -> o1.getAge() - o2.getAge());
        System.out.println(personList);
    }


    @Test
    public void test8() {
        /// 找出personList中年龄大于8的集合，并且打印出来
        personList.stream()
                .filter(person -> person.getAge() > 7)
                .forEach(System.out::println);
    }

    /**
     *集合的一些lambda写法
     */
    @SuppressWarnings("AlibabaRemoveCommentedCode")
    @Test
    public void test9() {
        /// 找出personList中年龄大于8的集合，排序后，并且打印出来
        personList.stream()
                .filter(person -> person.getAge() > 7)
                .sorted(Comparator.comparingInt(Person::getAge))
                .forEach(System.out::println);
    }

    @Test
    public void test10() {
        System.out.println(personList.stream()
                .min(Comparator.comparingInt(Person::getAge))
                .get());
    }

    @Test
    public void test11() {
        /// 找出personList中年龄大于8的集合，排序后，并且打印出来
        String collect = personList.stream()
                .filter(person -> person.getAge() > 7)
                .sorted(Comparator.comparingInt(Person::getAge))
                .map(Person::getName)
                .collect(Collectors.joining(","));
        /// 这一步使用 collect 转成String 返回失败;
        System.out.println(collect);
    }

    @Test
    public void test15() {
        /// 找出personList中年龄大于7的集合，排序后，并且打印出来
        Object[] objects = personList.stream()
                .filter(person -> person.getAge() > 7)
                .sorted(Comparator.comparingInt(Person::getAge))
                /// 返回的值
                .map(Person::getName)
                /// objects数组 这是4,这是3
                .toArray();

        /// 这一步使用 collect 转成String 返回失败;
        System.out.println(objects);
    }

    @Test
    public void test12() {
        List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
        /// 获取对应的平方数
        List<Integer> squaresList = numbers.stream()
                .map(i -> i * i)
                .distinct()
                .collect(Collectors.toList());
        System.out.println(squaresList);
    }

    /**
     * 统计测试
     */
    @Test
    public void test13(){
        List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
        IntSummaryStatistics stats = numbers.stream()
                .mapToInt(x -> x)
                .summaryStatistics();

        System.out.println("列表中最大的数 : " + stats.getMax());
        System.out.println("列表中最小的数 : " + stats.getMin());
        System.out.println("列表个数 : " + stats.getCount());
        System.out.println("所有数之和 : " + stats.getSum());
        System.out.println("平均数 : " + stats.getAverage());
    }

    /**
     * 数组的lambda写法
     */
    @Test
    public void test14(){
        /// 第一种
        Arrays.stream(persons).forEach(person -> log.info(person.toString()));

        /// 第二种,这种由第一种实现的
        Stream.of(persons).forEach(person -> log.info(person.toString()));
    }



    private void add(Integer... values) {
        int sum = Stream.of(values).reduce(0, Integer::sum);
        System.out.println(sum);
    }
}
